﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using DataModels.Common;
using DataModels.Models;

namespace GenericTools.Models
{
    [Serializable]
    public class ReportingError
    {
        internal const string DEFAULT_ERROR_MESSAGE = "Error in the reporting text";

        #region Error Translation Text Label IDs
        public const int NO_ERROR_LABEL = 6;
        public const int REPORT_DOES_NOT_EXIST_LABEL = 35;
        public const int WHITE_SPACE_PRESENT_LABEL = 38;
        public const int INVALID_FACILITY_LABEL = 36;
        public const int INVALID_YEAR_LABEL = 23;
        public const int INVALID_PERIOD_LABEL = 24;
        public const int MISSING_FACILITY_LABEL = 37;
        public const int FEW_REPORT_PARAMETERS_LABEL = 39;
        public const int BUSINESS_RULES_FAILURE_LABEL = 7;
        public const int NON_INTEGER_VALUE_LABEL = 9;
        public const int NON_DECIMAL_VALUE_LABEL = 10;
        public const int MISSING_SENDER_NUMBER_LABEL = 42;
        public const int INVALID_REPORT_INITIALIZATION_LABEL = 44;
        public const int REPORT_IS_VERY_OLD_LABEL = 45;
        public const int REPORT_HAS_FUTURE_RECORDS_LABEL = 46;
        public const int MANY_REPORT_PARAMETERS_LABEL = 40;
        public const int INVALID_OBJECT_LABEL = 41;
        public const int SENDER_NUMBER_IS_NOT_REGISTERED_LABEL = 43;
        public const int RESUBMIT_NON_EXISTING_REPORT_LABEL = 15;
        public const int REPORT_ALREADY_SUBMITTED_LABEL = 12;
        public const int SENDER_NUMBER_IS_NOT_REGISTERED_FOR_SELECTED_FACILITY_LABEL = 47;
        public const int SUCH_REPORT_IS_NOT_EXPECTED_FROM_FACILITY_LABEL = 48;
        public const int INVALID_TIMEFRAME_LABEL = 53;
        public const int CURRENT_MONTH_REPORTING_NOT_ALLOWED_LABEL = 72;

        public const int UNIGOLD_IS_MISSING_LABEL = 73;
        public const int DETERMINE_IS_MISSING_LABEL = 74;
        public const int DBS_IS_MISSING_LABEL = 75;
        public const int STOCK_MESSAGE_INVALID_LABEL = 76;

        #region Comparison
        public static int COMPARISON_LABEL = 54;
        public static int EQUALS_LABEL = 60;
        public static int NOT_EQUALS_LABEL = 61;
        public static int GREATER_THAN_LABEL = 62;
        public static int GREATER_THAN_OR_EQUALS_LABEL = 63;
        public static int LESS_THAN_LABEL = 64;
        public static int LESS_THAN_OR_EQUALS_LABEL = 65;
        #endregion

        public const int MISSING_REPORTS_LABEL = 67;
        public const int MISSING_REPORT_LABEL = 68;

        public const int INVALID_REPORT_AGE_CATEGORY_LABEL = 77;
        public const int INVALID_REPORT_FORMAT_AFTER_YEAR_LABEL = 78;
        public const int USER_NOT_AUTHORIZED_FOR_THIS_OPERATION_LABEL = 79;
        public const int SECTION_INDICATOR_VALUES_COULD_NOT_BE_RESOLVED_LABEL = 80;
        public const int MTUHA_REPORT_IS_NOT_KNOWN_OR_CONFIGURED_PROPERLY_LABEL = 81;
        public const int INVALID_AGE_CATEGORY_OR_REPORT_SECTION_LABEL = 82;
        public const int MTUHA_REPORT_MC_IS_QUARTERLY_REPORTED_LABEL = 83;
        #endregion

        private static Dictionary<ReportProcessingError, int> errorCodeTypeMapping = new Dictionary<ReportProcessingError, int>()
        {
            { ReportProcessingError.NO_ERROR,                           NO_ERROR_LABEL                          },
            { ReportProcessingError.WHITE_SPACE_PRESENT,                WHITE_SPACE_PRESENT_LABEL               },
            { ReportProcessingError.INVALID_REPORT_INITIALIZATION,      INVALID_REPORT_INITIALIZATION_LABEL     },
            { ReportProcessingError.INVALID_FACILITY,                   INVALID_FACILITY_LABEL                  },
            { ReportProcessingError.INVALID_PERIOD,                     INVALID_PERIOD_LABEL                    },
            { ReportProcessingError.INVALID_YEAR,                       INVALID_YEAR_LABEL                      },
            { ReportProcessingError.SENDER_NUMBER_IS_NOT_REGISTERED,    SENDER_NUMBER_IS_NOT_REGISTERED_LABEL   },
            { ReportProcessingError.REPORT_DOES_NOT_EXIST,              REPORT_DOES_NOT_EXIST_LABEL             },
            { ReportProcessingError.INVALID_REPORT_AGE_CATEGORY,        INVALID_REPORT_AGE_CATEGORY_LABEL       },
            { ReportProcessingError.MANY_REPORT_PARAMETERS,             MANY_REPORT_PARAMETERS_LABEL            },
            { ReportProcessingError.FEW_REPORT_PARAMETERS,              FEW_REPORT_PARAMETERS_LABEL             },
            { ReportProcessingError.NON_INTEGER_VALUE,                  NON_INTEGER_VALUE_LABEL                 },
            { ReportProcessingError.REPORT_HAS_FUTURE_RECORDS,          REPORT_HAS_FUTURE_RECORDS_LABEL         },
            { ReportProcessingError.INVALID_REPORT_FORMAT_AFTER_YEAR,   INVALID_REPORT_FORMAT_AFTER_YEAR_LABEL  },
            { ReportProcessingError.STOCK_MESSAGE_INVALID,              STOCK_MESSAGE_INVALID_LABEL             },
            { ReportProcessingError.MISSING_FACILITY,                   MISSING_FACILITY_LABEL                  },
            { ReportProcessingError.BUSINESS_RULES_FAILURE,             BUSINESS_RULES_FAILURE_LABEL            },
            { ReportProcessingError.NON_DECIMAL_VALUE,                  NON_DECIMAL_VALUE_LABEL                 },
            { ReportProcessingError.MISSING_SENDER_NUMBER,              MISSING_SENDER_NUMBER_LABEL             },
            { ReportProcessingError.REPORT_IS_VERY_OLD,                 REPORT_IS_VERY_OLD_LABEL                },
            { ReportProcessingError.INVALID_OBJECT,                     INVALID_OBJECT_LABEL                    },
            { ReportProcessingError.RESUBMIT_NON_EXISTING_REPORT,       RESUBMIT_NON_EXISTING_REPORT_LABEL      },
            { ReportProcessingError.REPORT_ALREADY_SUBMITTED,           REPORT_ALREADY_SUBMITTED_LABEL          },
            { ReportProcessingError.INVALID_TIMEFRAME,                  INVALID_TIMEFRAME_LABEL                 },
            { ReportProcessingError.UNIGOLD_IS_MISSING,                 UNIGOLD_IS_MISSING_LABEL                },
            { ReportProcessingError.DETERMINE_IS_MISSING,               DETERMINE_IS_MISSING_LABEL              },
            { ReportProcessingError.DBS_IS_MISSING,                     DBS_IS_MISSING_LABEL                    },
            { ReportProcessingError.MISSING_REPORTS,                    MISSING_REPORTS_LABEL                   },
            { ReportProcessingError.MISSING_REPORT,                     MISSING_REPORT_LABEL                    },
            { 
                ReportProcessingError.CURRENT_MONTH_REPORTING_NOT_ALLOWED, 
                CURRENT_MONTH_REPORTING_NOT_ALLOWED_LABEL 
            },
            { 
                ReportProcessingError.SUCH_REPORT_IS_NOT_EXPECTED_FROM_FACILITY, 
                SUCH_REPORT_IS_NOT_EXPECTED_FROM_FACILITY_LABEL
            },
            {
                ReportProcessingError.SENDER_NUMBER_IS_NOT_REGISTERED_FOR_SELECTED_FACILITY,  
                SENDER_NUMBER_IS_NOT_REGISTERED_FOR_SELECTED_FACILITY_LABEL
            },
            {
                ReportProcessingError.USER_NOT_AUTHORIZED_FOR_THIS_OPERATION,
                USER_NOT_AUTHORIZED_FOR_THIS_OPERATION_LABEL
            },
            {
                ReportProcessingError.SECTION_INDICATOR_VALUES_COULD_NOT_BE_RESOLVED,
                SECTION_INDICATOR_VALUES_COULD_NOT_BE_RESOLVED_LABEL
            },
            {
                ReportProcessingError.MTUHA_REPORT_IS_NOT_KNOWN_OR_CONFIGURED_PROPERLY,
                MTUHA_REPORT_IS_NOT_KNOWN_OR_CONFIGURED_PROPERLY_LABEL
            },
            { 
                ReportProcessingError.INVALID_AGE_CATEGORY_OR_REPORT_SECTION,
                INVALID_AGE_CATEGORY_OR_REPORT_SECTION_LABEL
            },
            {
                ReportProcessingError.MTUHA_REPORT_MC_IS_QUARTERLY_REPORTED,
                MTUHA_REPORT_MC_IS_QUARTERLY_REPORTED_LABEL
            }
        };

        public int Code { get; set; }
        public ReportProcessingError Type { get; set; }
        public string ErrorText { get; set; }
        public bool KnownError { get; set; }

        public ReportingError()
        {

        }

        public ReportingError(int code, ReportProcessingError type, string errorText, bool knownError)
        {
            Code = code;
            Type = type;
            ErrorText = errorText;
            KnownError = knownError;
        }

        public static ReportingError GetReportingError(int code, string cellnum = null)
        {
            if (errorCodeTypeMapping.ContainsValue(code))
            {
                ReportingError reportingError = null;
                foreach (ReportProcessingError e in errorCodeTypeMapping.Keys)
                {
                    int errorCode = errorCodeTypeMapping[e];
                    if (errorCode == code)
                    {
                        string errorText = Utilities.GetTranslationText(cellnum, errorCode);

                        reportingError = new ReportingError
                        {
                            Code = errorCode,
                            Type = e,
                            ErrorText = errorText,
                            KnownError = true
                        };
                        break;
                    }
                }
                return reportingError;
            }
            else
            {
                string errorText = Utilities.GetTranslationText(cellnum, INVALID_OBJECT_LABEL);
                var reportingError = new ReportingError
                {
                    Code = INVALID_OBJECT_LABEL,
                    Type = ReportProcessingError.INVALID_OBJECT,
                    ErrorText = errorText,
                    KnownError = false
                };
                return reportingError;
            }
        }

        public static ReportingError GetReportingError(ReportProcessingError type, string cellnum = "IQSMS")
        {
            if (errorCodeTypeMapping.ContainsKey(type))
            {
                ReportingError reportingError = null;
                foreach (ReportProcessingError e in errorCodeTypeMapping.Keys)
                {
                    if (e == type)
                    {
                        int errorCode = errorCodeTypeMapping[e];                    
                        string errorText = Utilities.GetTranslationText(cellnum, errorCode);

                        reportingError = new ReportingError
                        {
                            Code = errorCode,
                            Type = e,
                            ErrorText = errorText,
                            KnownError = true
                        };
                        break;
                    }
                }
                return reportingError;
            }
            else
            {
                string errorText = Utilities.GetTranslationText(cellnum, INVALID_OBJECT_LABEL);

                var reportingError = new ReportingError
                {
                    Code = INVALID_OBJECT_LABEL,
                    Type = ReportProcessingError.INVALID_OBJECT,
                    ErrorText = errorText,
                    KnownError = false
                };
                return reportingError;
            }
        }
    }
}
